package org.com.yz.dubbo.web.core;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.com.yz.common.constant.PayConstant;
import org.com.yz.common.util.ClassRefUtil;
import org.com.yz.common.util.MyLog;
import org.com.yz.common.util.ToolUtil;
import org.com.yz.dubbo.web.service.CheckMchAccntService;
import org.com.yz.dubbo.web.service.CheckTransService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName UniformDistributionAop
 * @Author wzc
 * @Date 2018/7/26 9:08
 **/


@Aspect
@Component
public class UniformDistributionAop {
    private final MyLog _log = MyLog.getLog(ParameterAop.class);

    @Autowired
    private CheckMchAccntService checkMchAccntService;

    @Autowired
    private CheckTransService checkTransService;


    @Pointcut(value = "@annotation(org.com.yz.common.annotion.UniformDistribution)")
    public void parameterVerification(){
    }


    /**
     * 参数校验公告参数
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("parameterVerification()")
    public Object doPermission(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        JSONObject po  = new JSONObject();
        String sign = "";
        String data="";
        String result="";
        try{
            //校验参数
            try{
                data = args[0].toString();
                sign = args[1].toString();
                result = StringEscapeUtils.unescapeJava(data);
                po = JSONObject.parseObject(result);
            }catch (Exception e){
                _log.info("解析参数出错：{"+ToolUtil.getExceptionMsg(e)+"}");
                return ClassRefUtil.createErrorRetData(po,sign,"500","请求参数不合法");
            }
            Map<String ,String> map = validateParams(po, sign,result);
            // 验证请求参数有效性（必选项）
            if(!map.get("code").equals("0000")){
                return ClassRefUtil.createErrorRetData(po,sign,map.get("code"),map.get("message"));
            }
            _log.info("参数校验通过");
            //如果都通过，就继续处理controller的逻辑（仍需校验每个接口都不同的bizContent）
            return point.proceed();
        }catch (Exception e){
            _log.info("系统错误：{}");
            return ClassRefUtil.createErrorRetData(po,sign,"500","系统出错，清联系项目组");
        }
    }


    /**
     * 验证公共参数
     * @param params
     * @return
     */
    private Map validateParams(JSONObject params, String sign,String data) {
        // 支付参数
        String mchNo = params.getString("mch_no"); 			    // 商户号
        String outTransNo = params.getString("out_trans_no");     // 请求追踪号
        String bizType = params.getString("biz_type");     // 交易类型
        System.out.println(bizType );
        String bizContent = params.getString("biz_content"); 	// 请求的业务数据
        String signType = params.getString("sign_type"); 	    // 签名加密方式
        String timestamp = params.getString("timestamp"); 		    // 请求时间
        //biz_type不在接口范围
        if(!checkBizeType(bizType)){
            return createMap(PayConstant.RETURN_DEPOSIT_BIZTYPE_NULL,PayConstant.RETURN_DEPOSIT_BIZTYPE_NULLS);
        }
        //自定义校验
        return checkMust(mchNo,outTransNo,bizType,bizContent,signType,timestamp);
    }



    //组装参数校验map
    private Map createMap(String code, String message){
        Map<String,String> resultMap = new HashMap<>();
        resultMap.put("code",code);
        resultMap.put("message",message);
        return resultMap;
    }

    //判断交易类型是否在接口范围内
    private boolean  checkBizeType(String bizType){
        for (String str : PayConstant.bizeTypes) {
            if(str.equals(bizType)){
                return true;
            }
        }
        return false;
    }


    //必输项校验
    private Map checkMust(String mchNo,String outTransNo,String bizType,String bizContent,String signType,String timestamp){
        String errorMessage;
        if(StringUtils.isBlank(mchNo)) {
            errorMessage = "商户号不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        if(StringUtils.isBlank(outTransNo)) {
            errorMessage = "请求追踪号不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        if(StringUtils.isBlank(bizType)) {
            errorMessage = "交易类型不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        if(StringUtils.isBlank(bizContent)) {
            errorMessage = "请求的业务数据不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        if(StringUtils.isBlank(signType)) {
            errorMessage = "签名加密方式不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        if(StringUtils.isBlank(timestamp)) {
            errorMessage = "请求时间戳不能为空";
            return createMap(PayConstant.RETURN_DEPOSIT_MUST_NULL,errorMessage);
        }
        return createMap("0000","");
    }


}
